package pchi.pchicamera;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import pchi.pchicamera.adapters.EffectAdapter;
import pchi.pchicamera.data.MyItemEffectHolder;
import pchi.pchicamera.functions.GetCameraID;
import pchi.pchicamera.functions.ImageEditting;
import pchi.pchicamera.helpers.BitmapHelpers;
import pchi.pchicamera.models.PhotoModel;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore.Images.Media;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;

public class MainActivity extends Activity implements OnClickListener,
		SurfaceHolder.Callback, Camera.PictureCallback, OnItemClickListener {

	private ListView listViewEffects;

	ArrayList<MyItemEffectHolder> effect = new ArrayList<MyItemEffectHolder>();

	int currentZoomLevel = 0, maxZoomLevel = 0;
	int MAX_ZOOM = 200;

	private Uri imageFileUri;

	private ZoomControls zoomControls;

	private Camera myCamera;
	private SurfaceView myCameraView;
	private SurfaceHolder mySurfaceHolder;

	private ImageButton btnSwitch;

	private int currentID = -1;
	private int frontID = -1;
	private int backID = -1;

	// private PhotoModel photoBack;
	private PhotoModel p;
	// private PhotoModel pFront;
	private Bundle bundle = new Bundle();

	private ImageButton btnCapture;
	private ImageButton btnEffects;
	private ImageButton btnAlbum;
	private ImageButton btnEditImageOfBackCamera;
	private ImageButton btnEditImageOfFrontCamera;
	private ImageButton btnTimer;
	private ImageButton btnFlash;

	private LinearLayout layoutRimer;
	private TextView countdownTextView;
	private ImageButton btnOkTimer;
	private ImageButton btnCancelTimer;
	private Handler timerUpdateHandler;
	int currentTime = 10;
	private int stateTimer = 1;
	private boolean timerRunning = false;

	private Boolean isOnFlash = false;

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		zoomControls = (ZoomControls) findViewById(R.id.zoomControl);

		btnEditImageOfBackCamera = (ImageButton) findViewById(R.id.imgPreviewBack);
		btnEditImageOfBackCamera.setOnClickListener(this);
		p = ImagePreview.getImagePreview(getApplicationContext());
		bundle.putString("imgPath", p.getPath());
		Bitmap imgpreview = BitmapHelpers.decodeFile(p.getPath(), 50, 70);
		btnEditImageOfBackCamera.setImageBitmap(imgpreview);

		btnEditImageOfFrontCamera = (ImageButton) findViewById(R.id.imgPreviewFront);
		btnEditImageOfFrontCamera.setOnClickListener(this);
		p = ImagePreview.getImagePreview(getApplicationContext());
		p = ImagePreview.getImagePreview(getApplicationContext());
		bundle.putString("imgPath", p.getPath());
		btnEditImageOfFrontCamera.setImageBitmap(BitmapHelpers.decodeFile(
				p.getPath(), 50, 70));

		btnFlash = (ImageButton) findViewById(R.id.btn_flat);
		btnFlash.setOnClickListener(this);

		layoutRimer = (LinearLayout) findViewById(R.id.layout_timer);
		layoutRimer.setVisibility(LinearLayout.INVISIBLE);

		btnTimer = (ImageButton) findViewById(R.id.btn_timer);
		btnTimer.setOnClickListener(this);

		btnOkTimer = (ImageButton) findViewById(R.id.btn_StartCountDownImageButton);
		btnOkTimer.setOnClickListener(this);
		timerUpdateHandler = new Handler();

		btnCancelTimer = (ImageButton) findViewById(R.id.btn_cancelcount);
		btnCancelTimer.setOnClickListener(this);

		countdownTextView = (TextView) findViewById(R.id.CountDownTextView);

		btnSwitch = (ImageButton) findViewById(R.id.btn_switch_camera);
		btnSwitch.setOnClickListener(this);

		btnCapture = (ImageButton) findViewById(R.id.btn_capture);
		btnCapture.setOnClickListener(this);

		btnEffects = (ImageButton) findViewById(R.id.btn_effect);
		btnEffects.setOnClickListener(this);

		btnAlbum = (ImageButton) findViewById(R.id.btn_album);
		btnAlbum.setOnClickListener(this);

		myCameraView = (SurfaceView) findViewById(R.id.CameraView);

		mySurfaceHolder = myCameraView.getHolder();
		mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		mySurfaceHolder.addCallback(this);

		backID = GetCameraID.getBackID(getApplicationContext());
		frontID = GetCameraID.getFrontID(getApplicationContext());
		currentID = backID;

		// if devices has not camera, we will return
		if (backID == -1)
			return;

		effect.add(new MyItemEffectHolder("None", R.drawable.ic_effect_none));

		effect.add(new MyItemEffectHolder("Aqua", R.drawable.ic_effect_aqua));

		effect.add(new MyItemEffectHolder("Mono", R.drawable.ic_effect_mono));

		effect.add(new MyItemEffectHolder("Negative",
				R.drawable.ic_effect_negative));

		effect.add(new MyItemEffectHolder("Posterize",
				R.drawable.ic_effect_posterize));

		effect.add(new MyItemEffectHolder("Sepia", R.drawable.ic_effect_sepia));

		effect.add(new MyItemEffectHolder("Solarize",
				R.drawable.ic_effect_solarize));

		listViewEffects = (ListView) findViewById(R.id.listview_effect);

		listViewEffects.setAdapter(new EffectAdapter(getApplicationContext(),
				effect));
		listViewEffects.setVisibility(View.INVISIBLE);
		listViewEffects.setOnItemClickListener(this);

	}

	@SuppressWarnings("deprecation")
	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		case R.id.btn_flat:
			if (isOnFlash) {
				isOnFlash = false;
				changedFlast(Camera.Parameters.FLASH_MODE_OFF, mySurfaceHolder);
				btnFlash.setBackgroundDrawable(getResources().getDrawable(
						R.drawable.ic_flast_off));
			} else {
				isOnFlash = true;
				changedFlast(Camera.Parameters.FLASH_MODE_ON, mySurfaceHolder);
				btnFlash.setBackgroundDrawable(getResources().getDrawable(
						R.drawable.ic_flast_on));
			}

			break;
		case R.id.btn_timer:
			layoutRimer.setVisibility(LinearLayout.VISIBLE);
			stateTimer = setTime(stateTimer);
			countdownTextView.setText("" + currentTime);
			break;
		case R.id.btn_StartCountDownImageButton:
			if (!timerRunning) {
				timerRunning = true;
				timerUpdateHandler.post(timerUpdateTask);
			}

			break;
		case R.id.btn_cancelcount:
			currentTime = 10;
			stateTimer = 1;
			timerRunning = false;
			layoutRimer.setVisibility(LinearLayout.INVISIBLE);
			break;
		case R.id.btn_switch_camera:
			zoomControls.setVisibility(ZoomControls.INVISIBLE);

			if (currentID == backID) {
				currentID = frontID;

			} else {

				currentID = backID;
			}
			myCamera.release();
			myCamera = Camera.open(currentID);
			myCameraView = (SurfaceView) findViewById(R.id.CameraView);

			try {
				myCamera.setPreviewDisplay(mySurfaceHolder);
			} catch (IOException e) {
				e.printStackTrace();
			}

			myCamera.setDisplayOrientation(90);
			myCamera.startPreview();
			mySurfaceHolder = myCameraView.getHolder();
			mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
			mySurfaceHolder.addCallback(this);

			myCameraView.invalidate();

			break;
		case R.id.btn_capture:
			myCamera.takePicture(null, null, this);
			break;
		case R.id.btn_album:
			Intent intentAlbum = new Intent(MainActivity.this,
					AlbumActivity.class);
			startActivity(intentAlbum);
			break;
		case R.id.btn_effect:
			listViewEffects.setVisibility(View.VISIBLE);
			break;
		case R.id.imgPreviewBack:
			Intent intentEditting = new Intent(MainActivity.this,
					EdittingImagesActivity.class);
			intentEditting.putExtra("BundleOfMain", bundle);
			startActivity(intentEditting);
			break;
		case R.id.imgPreviewFront:
			Intent intentEditting2 = new Intent(MainActivity.this,
					EdittingImagesActivity.class);
			intentEditting2.putExtra("BundleOfMain", bundle);
			startActivity(intentEditting2);
			break;

		default:
			break;
		}
	}

	private void changedFlast(String strFlash, SurfaceHolder mySur) {
		try {
			myCamera.setPreviewDisplay(mySur);
			Camera.Parameters parameters = myCamera.getParameters();
			parameters.setFlashMode(strFlash);
			myCamera.setParameters(parameters);
		} catch (Exception e) {
			myCamera.release();
		}
	}

	private int setTime(int _stateTimer) {
		switch (_stateTimer) {
		case 1:
			currentTime = 10;
			return 2;
		case 2:
			currentTime = 6;
			return 3;
		case 3:
			currentTime = 3;
			return 1;
		default:
			return 1;
		}
	}

	private Runnable timerUpdateTask = new Runnable() {
		public void run() {
			if (currentTime > 1) {

				currentTime--;
				timerUpdateHandler.postDelayed(timerUpdateTask, 1000);
			} else {
				myCamera.takePicture(null, null, MainActivity.this);
				timerRunning = false;
				countdownTextView.setVisibility(View.INVISIBLE);
				stateTimer = 1;
			}
			countdownTextView.setText("" + currentTime);
		}
	};

	@Override
	public void surfaceChanged(SurfaceHolder mHolder, int format, int width,
			int height) {
		myCamera.startPreview();
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		myCamera = Camera.open(currentID);

		try {
			myCamera.setPreviewDisplay(holder);
			final Camera.Parameters parameters = myCamera.getParameters();
			if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
				parameters.set("orientation", "portrait");

				// For Android Version 2.2 and above
				myCamera.setDisplayOrientation(90);

				// For Android Version 2.0 and above
				parameters.setRotation(90);
			}
			if (currentID == backID) {
				if (parameters.isZoomSupported()) {
					maxZoomLevel = parameters.getMaxZoom();

					zoomControls.setIsZoomInEnabled(true);
					zoomControls.setIsZoomOutEnabled(true);

					zoomControls
							.setOnZoomInClickListener(new OnClickListener() {
								public void onClick(View v) {
									if (currentZoomLevel < maxZoomLevel) {
										currentZoomLevel++;
										// camera.startSmoothZoom(currentZoomLevel);
										parameters.setZoom(currentZoomLevel);

										myCamera.setParameters(parameters);
									}
								}
							});

					zoomControls
							.setOnZoomOutClickListener(new OnClickListener() {
								public void onClick(View v) {
									if (currentZoomLevel > 0) {
										currentZoomLevel--;
										// camera.startSmoothZoom(currentZoomLevel);
										parameters.setZoom(currentZoomLevel);
										myCamera.setParameters(parameters);
									}
								}
							});
				}
				parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
			}

			myCamera.setParameters(parameters);

		} catch (IOException exception) {

		}

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		myCamera.stopPreview();
		myCamera.release();
	}

	@Override
	public void onPictureTaken(byte[] data, Camera camera) {

		ContentValues i = new ContentValues();

		imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,
				i);

		try {
			OutputStream imageFileOS = getContentResolver().openOutputStream(
					imageFileUri);
			imageFileOS.write(data);
			imageFileOS.flush();
			imageFileOS.close();

		} catch (FileNotFoundException e) {
			Toast t = Toast.makeText(getApplicationContext(), e.getMessage(),
					Toast.LENGTH_SHORT);
			t.show();
		} catch (IOException e) {
			Toast t = Toast.makeText(getApplicationContext(), e.getMessage(),
					Toast.LENGTH_SHORT);
			t.show();
		}

		p.setPath(ImagePreview.getRealPathFromURI(imageFileUri,
				getApplicationContext()));
		if (currentID == backID) {
			btnEditImageOfBackCamera.setImageBitmap(ImageEditting.Rotation(
					p.getPath(), 50, 50, new Matrix()));
		} else {
			btnEditImageOfFrontCamera.setImageBitmap(ImageEditting.Rotation(
					p.getPath(), 50, 50, new Matrix()));
		}
		bundle.putString("imgPath", p.getPath());

		camera.startPreview();
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		listViewEffects.setVisibility(View.INVISIBLE);
		switch (position) {
		case 0:// None
			changedEffectCamera(Camera.Parameters.EFFECT_NONE, mySurfaceHolder);
			break;
		case 1:// Aqua
			changedEffectCamera(Camera.Parameters.EFFECT_AQUA, mySurfaceHolder);
			break;
		case 2:// Mono
			changedEffectCamera(Camera.Parameters.EFFECT_MONO, mySurfaceHolder);
			break;
		case 3:// Negative
			changedEffectCamera(Camera.Parameters.EFFECT_NEGATIVE,
					mySurfaceHolder);
			break;
		case 4:// Posterize
			changedEffectCamera(Camera.Parameters.EFFECT_POSTERIZE,
					mySurfaceHolder);
			break;
		case 5:// Sepia
			changedEffectCamera(Camera.Parameters.EFFECT_SEPIA, mySurfaceHolder);
			break;
		case 6:// Solarize
			changedEffectCamera(Camera.Parameters.EFFECT_SOLARIZE,
					mySurfaceHolder);
			break;
		default:
			break;
		}
	}

	private void changedEffectCamera(String strEffectCamera,
			SurfaceHolder holder) {
		try {
			myCamera.setPreviewDisplay(holder);
			Camera.Parameters parameters = myCamera.getParameters();
			List<String> colorEffects = parameters.getSupportedColorEffects();
			Iterator<String> cei = colorEffects.iterator();
			while (cei.hasNext()) {
				String currentEffect = cei.next();
				if (currentEffect.equals(strEffectCamera)) {
					parameters.setColorEffect(strEffectCamera);
					break;
				}
			}
			myCamera.setParameters(parameters);
		} catch (Exception e) {
			myCamera.release();
		}
	}

}
